//------------------------------------------------------//
// libreseau.c
// librairie réseau
//-----------------------------------------------------//
// Auteur : Brondino Julien
// Date de dernière modification : 04-04-2007
//-----------------------------------------------------//
#include "libreseau.h"

int creer_serveur_tcp(int port, int max_client, int debug){
  /*******************************************************
     Cette fonction retourne le descripteur de la socket
     créée sur le port PORT acceptant MAX_CLIENT
   *******************************************************/

  int sockfd;  /* sockfd est le descripteur de la socket d'écoute */
  struct sockaddr_in my_addr;    /* Adresse du serveur */
  int sin_size;

  if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    fprintf(stderr, "Serveur : Impossible de creer la socket");
    return -1;
  }else if(debug){
    printf("Serveur : Socket creee avec le descripteur %d.\n", sockfd);
  }

  my_addr.sin_family = AF_INET;         /* Socket Internet */
  my_addr.sin_port = htons(port);       /* On affecte le port du serveur */
  my_addr.sin_addr.s_addr = INADDR_ANY; /* Auto-remplissage avec mon IP */
  bzero(&(my_addr.sin_zero), 8);        /* On met le reste de la structure a 0 */

  if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1){
    fprintf(stderr, "Serveur : Impossible d'ouvrir le port demandé : %d", port);
    return -1;
  }else if(debug){
    printf("Serveur : Port %d ouvert.\n", port);
  }

  if (listen(sockfd, max_client) == -1) {
    fprintf(stderr, "Serveur : Impossible d'ecouter %d clients", max_client);
    return -1;
  }else if(debug){
    printf("Serveur : %d client(s) sont attendus.\n", max_client);
  }
  return sockfd;
}

int attendre_client_tcp(int sockfd, int debug){
  /*******************************************************
     Cette fonction attend la connexion de client
   *******************************************************/
  int newfd = -1;
  int sin_size;
  sin_size = sizeof(struct sockaddr_in);
  struct sockaddr_in their_addr; /* Adresse du connecté  */

  if(debug)
    printf("Serveur : Attente d'un nouveau client.\n");

  if((newfd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1) {
    if(debug)
      fprintf(stderr, "Serveur : Impossible de se connecter au client.\n");
    return attendre_client_tcp(sockfd, debug);
  }else if(debug){
    printf("Serveur : Connexion à un nouveau client sur le descripteur %d.\n", newfd);
    printf("Serveur : Recu connection de %s\n", inet_ntoa(their_addr.sin_addr));
  }
  return newfd;
}

int creer_client_tcp(char * adresse, int port, int debug){
  /*******************************************************
     Cette fonction se connecte au serveur ADRESSE sur
     le port PORT
   *******************************************************/
  int sockfd;
  struct sockaddr_in their_addr; /* Adresse de celui qui se connecte */

  if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    fprintf(stderr, "Client  : Impossible de creer la socket");
    return -1;
  }else if(debug){
    printf("Client  : Socket creee avec le descripteur %d.\n", sockfd);
  }

  their_addr.sin_family = AF_INET;      /* Socket Internet */
  their_addr.sin_port = htons(port);    /* On affecte le port du serveur */
  their_addr.sin_addr.s_addr = inet_addr(adresse); /* On affecte l'adresse du serveur */
  bzero(&(their_addr.sin_zero), 8);     /* On met le reste de la structure a 0 */

  if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1) {
    fprintf(stderr, "Client  : Impossible d'etablir la connexion avec  %s sur le port %d.\n", inet_ntoa(their_addr.sin_addr), port);
    return -1;
  }else if(debug){
    printf("Client  : Connexion etablie avec %s sur le port %d.\n", inet_ntoa(their_addr.sin_addr), port);
  }

  return sockfd;
}

int ecrire(int sockfd, int taille, char * message){
  int nb_total = 0, nb_envoye = 0;
  char * msg = message;
  /*taille = strlen(message);*/

  while(nb_total < taille){
    nb_envoye = send(sockfd, msg, taille-nb_total, 0);
    if(nb_envoye == -1)
      return -1;
    nb_total += nb_envoye;
    msg += nb_envoye;
  }
  return nb_total;
}

int lire(int sockfd, char * message, int maxChar){
  int nb_total = 0, nb_lu = 0;
  char * msg = message;

  while(nb_lu == 0 || nb_total == maxChar){
    nb_lu = recv(sockfd, msg, maxChar - nb_total, 0);
    if(nb_lu == -1)
      return -1;
    nb_total += nb_lu;
    msg += nb_lu;
  }
  return nb_total;
}
